/**
 * 
 */
package pt.mleiria.crypto.skip;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.KeyAgreement;

import org.apache.commons.codec.binary.Base64;

/**
 * @author NB13712
 * 
 */
public class SkipClient {

	public static void main(String[] args) throws Exception {
		String host = args[0];
		int port = Integer.parseInt(args[1]);

		// Create a Diffie-Hellman key pair.
		KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH");
		kpg.initialize(Skip.sDHParameterSpec);
		KeyPair keyPair = kpg.genKeyPair();

		// Open the network connection.
		Socket socket = new Socket(host, port);
		DataOutputStream out = new DataOutputStream(socket.getOutputStream());
		DataInputStream in = new DataInputStream(socket.getInputStream());
		/*
		 * In SkipServer, we waited for a public key and then sent our own. In
		 * the client, the process is reversed. Send the public key
		 */
		byte[] keyBytes = keyPair.getPublic().getEncoded();
		out.writeInt(keyBytes.length);
		out.write(keyBytes);
		// Receive a public key.
		keyBytes = new byte[in.readInt()];
		in.readFully(keyBytes);
		KeyFactory kf = KeyFactory.getInstance("DH");
		X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(keyBytes);
		PublicKey theirPublicKey = kf.generatePublic(x509Spec);
		/*
		 * As in the server, we generate the secret value using our private key
		 * and the other party's public key.
		 */
		KeyAgreement ka = KeyAgreement.getInstance("DH");
		ka.init(keyPair.getPrivate());
		ka.doPhase(theirPublicKey, true);
		byte[] secret = ka.generateSecret();
		// Clean up.
		out.close();
		in.close();
		Base64 b64 = new Base64();
		System.out.println(new String(b64.encode(secret), "UTF-8"));
	}

}
